//
//  OPPost.m
//  OPFramework
//
//  Created by malcom on 7/12/08.
//  Copyright 2008 __MyCompanyName__. All rights reserved.
//

#import "OPPost.h"
#import "OPTopic.h"
#import "OPBoard.h"
#import "OPForum.h"
#import "OPBoard_Extensions.h"

@implementation OPPost

@synthesize p_postID;
@synthesize p_author;
@synthesize p_subject;
@synthesize p_message;
@synthesize p_postDate;

- (id) initLoadingPostWithID:(NSNumber *) _postid fromBoard:(OPBoard *) _board {
	self = [super init];
	if (self != nil) {
		p_postID = [_postid intValue];
		//obj_parentTopic = nil;
		_delegateBoard = [_board retain];
		_parentTopicID = -1;
		_parentForumID = -1;
		
		// init with an xml request
		if (![self _loadSyncWithID: _postid]) return nil;
	}
	return self;
}

		
- (BOOL) _loadSyncWithID:(NSNumber *) _postid {
	XMLRPCResponse *dataMessage = [_delegateBoard _executeRequestMethodNamed: @"msgs.getPostWithID" 
																  withParams: [NSArray arrayWithObject: _postid]
																  attachAuthData: NO];
	if (![dataMessage isFault]) {
		NSDictionary *dict = [dataMessage responseObject];
		[self _parseResultsForGetPostInfo: dict];
		return YES;
	} else return NO; 
}

- (void) _parseResultsForGetPostInfo:(NSDictionary *) dict {
		// subject
		[p_postDate release]; p_postDate = [[NSDate dateWithTimeIntervalSince1970: [[dict objectForKey:@"post_time"] longLongValue]] retain];
		
		// message
		[p_message release]; p_message = [[dict objectForKey: @"post_text"] retain];
		
		// author
		[p_author release]; p_author = [[_delegateBoard.obj_membersCache getUserMemberFromID: [NSNumber numberWithInt: [[dict objectForKey: @"poster_id"] intValue]] 
										 withName: [dict objectForKey: @"post_username"]] retain];
		
		[p_author refreshCompleteProfile];
		
		// parent forum id
		_parentForumID = [[dict objectForKey: @"forum_id"] intValue];
		
		// parent topic id
		_parentTopicID = [[dict objectForKey: @"topic_id"] intValue];
}

- (void) _loadResponseProperties:(NSDictionary *) _dict {
	// post id
	p_postID = [[_dict objectForKey: @"post_id"] intValue];
	
	// set subject
	if (p_subject != nil) [p_subject release];
	p_subject = [[_dict objectForKey: @"post_subject"] retain];
	
	// set message
	if (p_message != nil) [p_message release];
	p_message = [[_dict objectForKey: @"post_text"] retain];
	
	// post date
	if (p_postDate != nil) [p_postDate release];
	p_postDate = [[NSDate dateWithTimeIntervalSince1970: [[_dict objectForKey:@"post_time"] longLongValue]] retain];
	
	// create post's author or refresh it's data
	if (p_author != nil) [p_author release];
	p_author = [[_delegateBoard.obj_membersCache refreshUserCacheWithData: _dict] retain];
	
}

- (OPTopic *) getParentTopicObject {
	return [[self getParentForumObject] getCachedTopicWithID: [NSNumber numberWithInt: _parentTopicID]]; // link with an existing topic
}

- (OPForum *) getParentForumObject {
	return [_delegateBoard.obj_boardStructure getForumFromID: [NSNumber numberWithInt: _parentForumID]];
}

- (int) getPostPageIndexInTopic {	
	return [_delegateBoard getPostPageIdxOf: [NSNumber numberWithInt: p_postID] 
								inTopic:[NSNumber numberWithInt: _parentTopicID] 
									ofForum:[NSNumber numberWithInt: _parentForumID]];
}

// async response
#define _OPTopic_TopicsList				@"topic_messages"

- (void)connection: (XMLRPCConnection *)connection didReceiveResponse:(XMLRPCResponse *)response forMethod: (NSString *)method {
	// super class check if it's an error, a numeric response or simply some data to parse
	if (![self _checkErrorInRawResponseFromServer: response forMethod:method]) {
		// data update to parse
		[self _loadResponseProperties: [(NSDictionary *)[response responseObject] objectForKey: _OPTopic_TopicsList]];
		// we can propagate the result to listeners
		[self dataUpdatedFor: self atMethod:method];	
	}
}


- (void) dataUpdatedFor:(OPBaseObject *) _obj atMethod:(NSString *) _method {
	[super dataUpdatedFor: self atMethod: _method];
}

- (NSString *) description {
	return [NSString stringWithFormat: @"OPPost %d (%@) by author name %@ (id: %d) len %d bytes",p_postID,p_subject,p_author.p_username,p_author.p_userid,[p_message length]];
}


- (id) _initByLoadingResponsePostObject:(NSDictionary *) _dict fromTopicNumber:(NSNumber *) _num ofForum:(OPForum *) _forum {
	self = [super init];
	if (self != nil) {
		p_postID = [[_dict objectForKey: OPPost_PostID] intValue];
		//obj_parentTopic = [_topic retain];
		_parentForumID = _forum._forumID;
		_parentTopicID = [_num intValue];
		_delegateBoard = [_forum._delegateBoard retain];
		
		// load data
		[self _loadResponseProperties: _dict];
	}
	return self;
}

- (id) _initByLoadingResponsePostObject:(NSDictionary *) _dict fromTopic:(OPTopic *) _topic {
	self = [super init];
	if (self != nil) {

		p_postID = [[_dict objectForKey: OPPost_PostID] intValue];
		//obj_parentTopic = [_topic retain];
		_parentForumID = _topic.obj_parentForum._forumID;
		_parentTopicID = [_topic.p_topicID intValue];
		_delegateBoard = [_topic._delegateBoard retain];
		
		// load data
		[self _loadResponseProperties: _dict];
	}
	return self;
}

- (void) dealloc {
	[p_subject release];
	[p_message release];
	[p_postDate release];
	[p_author release];
	
	[super dealloc];
}

#define _method_deletePost	@"msg_sending.deletePost" 

- (BOOL) deleteFromServerAndResetPagesCache:(BOOL) _resetTopicPages withPassword:(NSString *) _password {
	NSArray *_params = [NSArray arrayWithObjects: [NSNumber numberWithInt: _parentForumID],
													[NSNumber numberWithInt: _parentTopicID],
													[NSNumber numberWithInt: p_postID],
													(_password == nil ? @"" : _password),nil];
	
	XMLRPCResponse *deleteTask = [_delegateBoard _executeRequestMethodNamed: _method_deletePost
																   withParams: _params
															   attachAuthData: NO];
	BOOL err = NO;
	// it's not an error response, we can update data
	if (! (err = [self _checkErrorInRawResponseFromServer: deleteTask forMethod: _method_deletePost ]) )
		// remove me from cache
		if (_resetTopicPages) [[self getParentTopicObject].obj_postsPages clear]; // clear all pages cache from the related topic
		else [[self getParentTopicObject].obj_postsPages removeElementFromPages: self]; // clear only the element from specifi page of related topic
	
	return !err;
}

- (BOOL) _isNumericResponseFromServerAnErrorCode:(NSNumber *) _code forMethod:(NSString *) method {
	switch ([_code intValue]) {
		case OFAPI_DELETED_OWN_POST:
		case OFAPI_POST_DELETED:
			return NO; break;
		default:
			return YES;
	}
	_lastErrorCode = [_code intValue];
	return NO;
}

@end
